<template>
    <view
        class="exam-checkbox"
        :style="[checkboxStyle]"
        :class="[`exam-checkbox-label--${parentData.placement}`]"
    >
        <view
            class="exam-checkbox__icon-wrap"
            @tap.stop="iconClickHandler"
            :style="[iconWrapStyle]"
        >
            <slot name="icon">
                <u-icon
                    class="exam-checkbox__icon-wrap__icon"
                    name="checkbox-mark"
                    :size="elIconSize"
                    :color="elIconColor"
                />
            </slot>
        </view>
        <view class="exam-checkbox__label" @tap.stop="labelClickHandler">
            <slot />
        </view>
    </view>
</template>

<script>
export default {
    name: "exam-checkbox",
    props: {
        // checkbox的名称
        name: {
            type: [String, Number, Boolean],
            default: "",
        },
        // 整体的大小
        size: {
            type: [String, Number],
            default: "",
        },
        // 是否默认选中
        checked: {
            type: Boolean,
            default: false,
        },
        // 是否禁用
        disabled: {
            type: [String, Boolean],
            default: "",
        },
        // 选中状态下的颜色
        activeColor: {
            type: String,
            default: "",
        },
        // 禁用状态下的颜色
        disabledColor: {
            type: String,
            default: "",
        },
        // 未选中的颜色
        inactiveColor: {
            type: String,
            default: "",
        },
        // 图标的大小，单位px
        iconSize: {
            type: [String, Number],
            default: "",
        },
        // 图标颜色
        iconColor: {
            type: String,
            default: "",
        },
        // 是否禁止点击提示语选中复选框
        labelDisabled: {
            type: [String, Boolean],
            default: "",
        },
        // 样式
        customStyle: {
            type: Object,
            default: () => {
                return {};
            },
        },
    },
    data() {
        return {
            isChecked: false,
            // 父组件的默认值，因为头条小程序不支持在computed中使用this.parent.shape的形式
            // 故只能使用如此方法
            parentData: {
                iconSize: 24,
                labelDisabled: null,
                disabled: null,
                activeColor: null,
                disabledColor: null,
                inactiveColor: null,
                size: 36,
                value: null,
                iconColor: null,
                placement: "row",
            },
        };
    },
    computed: {
        // 是否禁用，如果父组件exam-raios-group禁用的话，将会忽略子组件的配置
        elDisabled() {
            return this.disabled !== ""
                ? this.disabled
                : this.parentData.disabled !== null
                ? this.parentData.disabled
                : false;
        },
        // 是否禁用label点击
        elLabelDisabled() {
            return this.labelDisabled !== ""
                ? this.labelDisabled
                : this.parentData.labelDisabled !== null
                ? this.parentData.labelDisabled
                : false;
        },
        // 组件尺寸，对应size的值，默认值为21px
        elSize() {
            return this.size
                ? this.size
                : this.parentData.size
                ? this.parentData.size
                : 21;
        },
        // 组件的勾选图标的尺寸，默认12px
        elIconSize() {
            return this.iconSize
                ? this.iconSize
                : this.parentData.iconSize
                ? this.parentData.iconSize
                : 12;
        },
        // 组件选中激活时的颜色
        elActiveColor() {
            return this.activeColor
                ? this.activeColor
                : this.parentData.activeColor
                ? this.parentData.activeColor
                : "#2979ff";
        },
        // 组件未选中激活时的颜色
        elInactiveColor() {
            return this.inactiveColor
                ? this.inactiveColor
                : this.parentData.inactiveColor
                ? this.parentData.inactiveColor
                : "#B7BAC1";
        },
        // 组件选中禁用激活时的颜色
        elDisabledColor() {
            return this.disabledColor
                ? this.disabledColor
                : this.parentData.disabledColor
                ? this.parentData.disabledColor
                : "#2979ff";
        },
        elIconColor() {
            const iconColor = this.iconColor
                ? this.iconColor
                : this.parentData.iconColor
                ? this.parentData.iconColor
                : "#ffffff";
            // 图标的颜色
            if (this.elDisabled) {
                // disabled状态下，已勾选的checkbox图标改为elInactiveColor
                return this.isChecked ? this.elInactiveColor : "transparent";
            } else {
                return this.isChecked ? iconColor : "transparent";
            }
        },
        iconWrapStyle() {
            // checkbox的整体样式
            const style = {};
            if (this.elDisabled) {
                style.backgroundColor = this.isChecked
                    ? this.elDisabledColor
                    : "transparent";
                style.borderColor = this.isChecked
                    ? this.elDisabledColor
                    : this.elInactiveColor;
            } else {
                style.backgroundColor = this.isChecked
                    ? this.elActiveColor
                    : "#ffffff";
                style.borderColor = this.isChecked
                    ? this.elActiveColor
                    : this.elInactiveColor;
            }
            style.width = this.$u.addUnit(this.elSize);
            style.height = this.$u.addUnit(this.elSize);
            return style;
        },
        checkboxStyle() {
            const style = {};
            if (this.parentData.placement === "column") {
                style.paddingBottom = "10px";
            }
            return uni.$u.deepMerge(style, this.customStyle);
        },
    },
    mounted() {
        this.init();
    },
    methods: {
        init() {
            // 支付宝小程序不支持provide/inject，所以使用这个方法获取整个父组件，在created定义，避免循环引用
            this.updateParentData();
            if (!this.parent) {
                console.error(
                    "exam-checkbox必须搭配exam-checkbox-group组件使用"
                );
            }
            // 设置初始化时，是否默认选中的状态，父组件exam-checkbox-group的value可能是array，所以额外判断
            if (this.checked) {
                this.isChecked = true;
            } else if (this.$u.test.array(this.parentData.value)) {
                // 查找数组是是否存在this.name元素值
                this.isChecked = this.parentData.value.some((item) => {
                    return item === this.name;
                });
            }
        },
        updateParentData() {
            this.getParentData("exam-checkbox-group");
        },
        // 点击图标
        iconClickHandler(e) {
            this.preventEvent(e);
            // 如果整体被禁用，不允许被点击
            if (!this.elDisabled) {
                this.setRadioCheckedStatus();
            }
        },
        // 点击label
        labelClickHandler(e) {
            this.preventEvent(e);
            // 如果按钮整体被禁用或者label被禁用，则不允许点击文字修改状态
            if (!this.elLabelDisabled && !this.elDisabled) {
                this.setRadioCheckedStatus();
            }
        },
        emitEvent() {
            this.$emit("change", this.isChecked);
        },
        // 改变组件选中状态
        setRadioCheckedStatus() {
            // 将本组件标记为与原来相反的状态
            this.isChecked = !this.isChecked;
            this.emitEvent();
            typeof this.parent.unCheckedOther === "function" &&
                this.parent.unCheckedOther(this);
        },
        // 阻止事件冒泡
        preventEvent(e) {
            e && typeof e.stopPropagation === "function" && e.stopPropagation();
        },
        getParentData(parentName = "") {
            // 避免在created中去定义parent变量
            if (!this.parent) this.parent = {};
            // 这里的本质原理是，通过获取父组件实例(也即类似u-radio的父组件u-radio-group的this)
            this.parent = uni.$u.$parent.call(this, parentName);
            if (this.parent.children) {
                // 如果父组件的children不存在本组件的实例，才将本实例添加到父组件的children中
                this.parent.children.indexOf(this) === -1 &&
                    this.parent.children.push(this);
            }
            if (this.parent && this.parentData) {
                // 历遍parentData中的属性，将parent中的同名属性赋值给parentData
                Object.keys(this.parentData).map((key) => {
                    this.parentData[key] = this.parent[key];
                });
            }
        },
    },
    watch: {
        checked() {
            this.isChecked = this.checked;
        },
    },
};
</script>

<style lang="scss" scoped>
.exam-checkbox {
    display: flex;
    align-items: flex-start;
    overflow: hidden;

    &__icon-wrap {
        display: flex;
        align-items: center;
        justify-content: center;
        border-width: 1px;
        border-style: solid;
    }

    &__label {
        margin-left: 10rpx;
        color: $edu-main-color;
        font-size: 30rpx;
    }
}
.exam-checkbox-label--column {
    .exam-checkbox {
        &__label {
            flex: 1;
        }
    }
}
</style>
